package chess.view;

import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.Hashtable;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DragDetectEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.Bundle;

import chess.Activator;
import chess.controller.BoardController;
import chess.utils.ChessBoardParser;
import chess.utils.Convertor;
import chess.utils.Style12;

public class ChessBoard extends ViewPart implements PropertyChangeListener {

	// Color[] colors = { SWT., black };

	public static final String ID = "chess.view.chessBoard";

	private Canvas canvas;
	private int height = 48;
	private int width = 48;

	private int dragX;
	private int dragY;

	private String[][] positions = new String[8][8];

	private String piecesPath;

	private Hashtable<String, Image> pieces = new Hashtable<String, Image>();

	private Color colors[] = new Color[2];

	private boolean[][] isPressed = new boolean[8][8];
	private boolean[][] moves = new boolean[8][8];

	private int[][] memory = new int[2][2];
	private String from = "";
	private int which = 0;

	private int[] reverse = { 8, 7, 6, 5, 4, 3, 2, 1 };
	private int[] reverse3 = { 1, 2, 3, 4, 5, 6, 7, 8 };
//	private int[] reverse2 = { 7, 6, 5, 4, 3, 2, 1, 0 };
//	private int[] reverse4 = { 0, 1, 2, 3, 4, 5, 6, 7 };

	private String rating1 = "1999";
	private String rating2 = "984";

	private Dimension boardSize = new Dimension(height * 8, width * 8);
	private int boardposition = width * 8 + 20;
	private int boardheight = height * 8;;

	private BoardController controller;

	private Style12 style;

	private String draggedPiece = "";

	private boolean red;

//	private boolean flip = true;

	public ChessBoard() {
		Bundle bundle = Platform.getBundle("Chess");
		controller = new BoardController();
		style = new Style12("Player", "Player", "39", "39", 0, 0, true);

		try {
			piecesPath = FileLocator.resolve(
					bundle.getEntry("/Resources/pieces/")).getPath().trim();
		} catch (IOException e1) {
			e1.printStackTrace();
		}

	}

	@Override
	public void createPartControl(Composite parent) {

		canvas = new Canvas(parent, SWT.NONE);
		canvas.setBackground(canvas.getDisplay()
				.getSystemColor(SWT.COLOR_WHITE));
		colors[1] = canvas.getDisplay()
				.getSystemColor(SWT.COLOR_LIST_SELECTION);
		colors[0] = canvas.getDisplay().getSystemColor(SWT.COLOR_GRAY);
		canvas.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true,
				true));

		Activator.getDefault().getChessBoardPos().addPropertyChangeListener(
				this);

		final Image p = new Image(canvas.getDisplay(), piecesPath + "bp.png");
		final Image b = new Image(canvas.getDisplay(), piecesPath + "bb.png");
		final Image k = new Image(canvas.getDisplay(), piecesPath + "bk.png");
		final Image n = new Image(canvas.getDisplay(), piecesPath + "bn.png");
		final Image q = new Image(canvas.getDisplay(), piecesPath + "bq.png");
		final Image r = new Image(canvas.getDisplay(), piecesPath + "br.png");
		final Image P = new Image(canvas.getDisplay(), piecesPath + "wp.png");
		final Image B = new Image(canvas.getDisplay(), piecesPath + "wb.png");
		final Image K = new Image(canvas.getDisplay(), piecesPath + "wk.png");
		final Image N = new Image(canvas.getDisplay(), piecesPath + "wn.png");
		final Image Q = new Image(canvas.getDisplay(), piecesPath + "wq.png");
		final Image R = new Image(canvas.getDisplay(), piecesPath + "wr.png");

		pieces.put("p", new Image(canvas.getDisplay(), p.getImageData()
				.scaledTo(width, height)));
		pieces.put("b", new Image(canvas.getDisplay(), b.getImageData()
				.scaledTo(width, height)));
		pieces.put("k", new Image(canvas.getDisplay(), k.getImageData()
				.scaledTo(width, height)));
		pieces.put("n", new Image(canvas.getDisplay(), n.getImageData()
				.scaledTo(width, height)));
		pieces.put("q", new Image(canvas.getDisplay(), q.getImageData()
				.scaledTo(width, height)));
		pieces.put("r", new Image(canvas.getDisplay(), r.getImageData()
				.scaledTo(width, height)));
		pieces.put("P", new Image(canvas.getDisplay(), P.getImageData()
				.scaledTo(width, height)));
		pieces.put("B", new Image(canvas.getDisplay(), B.getImageData()
				.scaledTo(width, height)));
		pieces.put("K", new Image(canvas.getDisplay(), K.getImageData()
				.scaledTo(width, height)));
		pieces.put("N", new Image(canvas.getDisplay(), N.getImageData()
				.scaledTo(width, height)));
		pieces.put("Q", new Image(canvas.getDisplay(), Q.getImageData()
				.scaledTo(width, height)));
		pieces.put("R", new Image(canvas.getDisplay(), R.getImageData()
				.scaledTo(width, height)));

		canvas.addMouseListener(new MouseAdapter() {
			// public void mouseDown(MouseEvent e) {
			// mouseClickDown(e);
			// }

			public void mouseUp(MouseEvent e) {
				mouseClickUp(e);
			}
		});

		// canvas.addDragDetectListener(new DragDetectListener() {
		// public void dragDetected(DragDetectEvent e) {
		// mouseMoveDrag(e);
		// // System.out.println("DRAG");
		// }
		// });

		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				Rectangle clientArea = canvas.getClientArea();
				width = clientArea.height / 8;
				height = clientArea.height / 8;
				boardheight = clientArea.height;
				boardposition = clientArea.height + 20;

				e.gc.setBackground(canvas.getDisplay().getSystemColor(
						SWT.COLOR_CYAN));

				int a = 0;
				for (int y = 0; y < height * 8; y += height) {
					for (int x = 0; x < width * 8; x += width) {
						e.gc.setBackground(colors[a % 2]);
						if (isPressed[x / width][y / height] == true) {
							e.gc.setBackground(canvas.getDisplay()
									.getSystemColor(SWT.COLOR_RED));
						} else if (moves[x / width][y / height] == true) {
							e.gc.setBackground(canvas.getDisplay()
									.getSystemColor(SWT.COLOR_BLUE));
						}
						e.gc.fillRectangle(x, y, width, height);
						a++;
					}
					a++;
				}

				int desetina = width / 20;
				for (int y = 0; y < height * 8; y += height) {
					for (int x = 0; x < width * 8; x += width) {
						e.gc.setBackground(colors[a % 2]);
						e.gc.fillRectangle(x + desetina, y + desetina, width
								- (2 * desetina), height - (2 * desetina));
						a++;
					}
					a++;
				}

				Font big = new Font(canvas.getDisplay(), "Arial", 20, SWT.BOLD);
				Font small = new Font(canvas.getDisplay(), "Arial", 14,
						SWT.NORMAL);
				e.gc.setFont(big);
				e.gc.setBackground(canvas.getDisplay().getSystemColor(
						SWT.COLOR_WHITE));

				if (style.getFlip()) {
					e.gc.drawString(style.getName1(), boardposition,
							boardheight / 10);
					e.gc.drawString(style.getName2(), boardposition,
							(boardheight / 10) * 8);
					e.gc.setFont(small);
					e.gc.drawString(rating1, boardposition,
							(boardheight / 10) - 25);
					e.gc.drawString(rating2, boardposition,
							(boardheight / 10) * 9);
					e.gc.drawString(style.getMaterialStrength1(),
							boardposition, ((boardheight / 10) * 5) - 38);
					e.gc.drawString(style.getMaterialStrength2(),
							boardposition, ((boardheight / 10) * 5) + 2);
					e.gc.setBackground(canvas.getDisplay().getSystemColor(
							SWT.COLOR_BLUE));
					e.gc.fillRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) - 38, Integer
									.valueOf(style.getMaterialStrength1()) * 3,
							15, 5, 5);
					e.gc.fillRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) + 2, Integer.valueOf(style
									.getMaterialStrength2()) * 3, 15, 5, 5);
					// e.gc.setColor(Color.BLACK);
					e.gc.drawRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) - 38, Integer
									.valueOf(style.getMaterialStrength1()) * 3,
							15, 5, 5);
					e.gc.drawRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) + 2, Integer.valueOf(style
									.getMaterialStrength2()) * 3, 15, 5, 5);
					// }
				} else {
					e.gc.drawString(style.getName1(), boardposition,
							(boardheight / 10) * 9);
					e.gc.drawString(style.getName2(), boardposition,
							boardheight / 10);
					e.gc.setFont(small);
					e.gc.drawString(rating1, boardposition,
							((height / 10) * 9) + 15);
					e.gc.drawString(rating2, boardposition, (height / 10) - 25);
					e.gc.drawString(style.getMaterialStrength1(),
							boardposition, ((height / 10) * 5) - 25);
					e.gc.drawString(style.getMaterialStrength2(),
							boardposition, ((height / 10) * 5) + 15);
					e.gc.setBackground(canvas.getDisplay().getSystemColor(
							SWT.COLOR_BLUE));
					e.gc.fillRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) - 38, Integer
									.valueOf(style.getMaterialStrength2()) * 3,
							15, 5, 5);
					e.gc.fillRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) + 2, Integer.valueOf(style
									.getMaterialStrength1()) * 3, 15, 5, 5);
					e.gc.drawRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) + 2, Integer.valueOf(style
									.getMaterialStrength1()) * 3, 15, 5, 5);
					e.gc.drawRoundRectangle(boardposition + 25,
							((boardheight / 10) * 5) - 38, Integer
									.valueOf(style.getMaterialStrength2()) * 3,
							15, 5, 5);
				}
				
				System.out.println();
				ChessBoardParser.printArray(positions);
				System.out.println();

				for (int y = 0; y < height * 8; y += height) {
					for (int x = 0; x < width * 8; x += width) {
						if (positions[x / width][y / height] != null
								&& !positions[x / width][y / height]
										.equals("-")) {
							e.gc.drawImage(pieces.get(positions[x / width][y
									/ height]), x, y);
						}
					}
				}

				if (!draggedPiece.equals("")) {
					e.gc.drawImage(pieces.get(draggedPiece),
							dragX - height / 2, dragY - width / 2);
				}
			}
		});
	}

	private void mouseClickDown(MouseEvent e) {
		if (e.button == 1) {
			if (!positions[e.x / width][e.y / height].equals("-")) {
				draggedPiece = positions[e.x / width][e.y / height];
				positions[e.x / width][e.y / height] = "-";
			}
			dragX = e.x;
			dragY = e.y;
			pressed(e);
		}
	}

	private void mouseMoveDrag(DragDetectEvent e) {
		// System.out.println("DRAG");
		dragX = e.x;
		dragY = e.y;
		// this.canvas.getDisplay().asyncExec(new Runnable() {
		// public void run() {
		canvas.redraw();
		// }
		// });
	}

	private void mouseClickUp(MouseEvent e) {
//		positions[e.x / width][e.y / height] = draggedPiece;
//		draggedPiece = "";
		pressed(e);
	}

	public void switchPressed(int x, int y) {
		isPressed[x][y] = !isPressed[x][y];
		if (isPressed[x][y]) {
			System.out.println(x + "," + y);
		}
		canvas.redraw();
	}

	public boolean getPressed(int x, int y) {
		return isPressed[x][y];
	}

	private void drop(MouseEvent e) {
		positions[e.x / width][e.y / height] = draggedPiece;
		draggedPiece = "";
		pressed(e);
	}

	private void pressed(MouseEvent arg0) {
		if (arg0.x < boardSize.width && arg0.y < boardSize.height) {
			switchPressed(arg0.x / width, arg0.y / height);
			// System.out.println(arg0.x / width + "," + arg0.y / height);
			red = getPressed(arg0.x / width, arg0.y / height);
			memory[which][0] = arg0.x;
			memory[which][1] = arg0.y;

			if (style.getFlip()) {
				from = from.concat(Convertor.numberToLetter((arg0.x + width)
						/ width));
				from = from.concat(String
						.valueOf(reverse[((arg0.y + height) / height) - 1]));
			} else {
				from = from.concat(Convertor.numberToLetter((arg0.x + width)
						/ width));
				from = from.concat(String
						.valueOf(reverse3[((arg0.y + height) / height) - 1]));
			}

			if (red) {
				which++;
			} else {
				which--;
				from = from.substring(0, from.length() - 4);
			}
			if (which > 1) {
				controller.sendMove(from);
				from = "";
				which = 0;
				switchPressed(memory[0][0] / width, memory[0][1] / height);
				switchPressed(memory[1][0] / width, memory[1][1] / height);
			}
		}
	}

	public void propertyChange(PropertyChangeEvent evt) {
		if ("all".equals(evt.getPropertyName())) { //$NON-NLS-1$
			System.out.println("property change");
			this.style = (Style12) evt.getNewValue();
			this.positions = style.getBoardPositions();
			this.canvas.getDisplay().asyncExec(new Runnable() {
				public void run() {
					canvas.redraw();
				}
			});
		}
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}
}
